package edu.uwm.universitydb.tests;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import edu.uwm.universitydb.db.connection.DBConnectionFactory;
import edu.uwm.universitydb.framework.exception.DataAccessException;

public abstract class PerformanceTest {

	public abstract String getName();

	public abstract String getQuery();
	
	public abstract String[] getAddIndex();
	
	abstract String[] getDropIndex();
	
	public Long getBeforeTime() {
		return _beforeTime;
	}
	
	public Long getAfterTime() {
		return _afterTime;
	}

	private void dropIndexes(Connection connection) {
		for(String cmd : getDropIndex()) {
			this.executeQuery(connection, cmd);
		}
	}
	

	private void createIndex(Connection connection) {
		for(String cmd : getAddIndex()) {
			this.executeQuery(connection, cmd);
		}
	}

	
	public boolean execute() {
		Long startTime,endTime;
        PreparedStatement pStmt = null;
		Connection connection = null;
		try {
			connection = DBConnectionFactory.getInstance().getDBConnection();
			pStmt = connection.prepareStatement(getQuery());
			
			//Run query without Index
			startTime = System.currentTimeMillis();
			pStmt.executeQuery();
			endTime = System.currentTimeMillis();
			_beforeTime = endTime - startTime;
			
			//Create Index
			this.createIndex(connection);
			
			//Run query with Index
			startTime = System.currentTimeMillis();
			pStmt.executeQuery();
			endTime = System.currentTimeMillis();
			_afterTime = endTime - startTime;

			//Drop Index
			this.dropIndexes(connection);
			
		} catch (DataAccessException | SQLException e) {
			e.printStackTrace();
			return false;
		} finally {
			if (pStmt != null) {
				try {
					pStmt.close();
					connection.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
		return true;
	}
	
	private void executeQuery(Connection connection, String query) {
		try {
			PreparedStatement pStmt = connection.prepareStatement(query);
			pStmt.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	private Long _beforeTime;
	private Long _afterTime;
	
	
}
